﻿using FluentValidation;
using Nuclear.Models.DtoModels;
using Nuclear.Utils;

namespace Nuclear.Validations.DtoValidations;
using static Statics;

public class GenerateConsumeCodeRequestDtoValidator: AbstractValidator<GenerateConsumeCodeRequestDto>
{
    public GenerateConsumeCodeRequestDtoValidator()
    {
        RuleFor(x => x.SystemId)
            .Must(x => x.Length >= 2 && char.IsAsciiLetterUpper(x[0]) &&
                       x.All(char.IsAsciiLetterOrDigit))
            .WithErrorCode("System ID must be at least 2 alphanumeric characters and starts with upper letter")
            .WithMessage("系统ID至少要有两个字母或数字, 首字符必须是大写字母");
        RuleFor(x => x.MerchantId).NotEmpty()
            .WithErrorCode("Merchant ID must not be empty")
            .WithMessage("商户ID不能为空");
        RuleFor(x => x.ProductId).NotEmpty()
            .WithErrorCode("Product ID must not be empty")
            .WithMessage("产品ID不能为空");
        RuleFor(x => x.UserId)
            .Must(x => x.Length == ChinaMainlandPhoneNumberLength && 
                       x[0] == '1' && 
                       x.All(char.IsDigit))
            .WithErrorCode("User ID must be a China mainland mobile phone number")
            .WithMessage("用户ID必须是中国大陆手机号码");

        RuleFor(x => x.Prefix)
            .Must(x => x.Length == ConsumeCodePrefixLength &&
                       x.All(char.IsAsciiLetterUpper))
            .WithErrorCode($"Consume code prefix must be {ConsumeCodeLength} upper letters")
            .WithMessage($"消费码前缀必须是{ConsumeCodeLength}大写字母");

        RuleFor(x => x.ValidFrom)
            .Must(x => x >= DateOnlyUtils.Today())
            .WithErrorCode($"Invalid date format or the date is in the past")
            .WithMessage($"日期格式错误或者日期在过去");

        RuleFor(x => x.ValidTo)
            .Must(x => x > DateOnlyUtils.Today())
            .WithErrorCode($"Invalid date format or the date is not in the future")
            .WithMessage($"日期格式错误或者日期不在未来");

        RuleFor(x => x.BenefitsCardNo)
            .Must(x =>
            {
                if (string.IsNullOrEmpty(x))
                    return true;

                return x.Length >= MinBenefitsCardNoLength &&
                       char.IsAsciiDigit(x[0]) && x[0] != '0' &&
                       x.All(char.IsAsciiDigit);
            })
            .WithErrorCode($"The benefits card NO. must be all digits and cannot be less than {MinBenefitsCardNoLength} digits")
            .WithMessage($"权益卡号必须全部是数字并至少{MinBenefitsCardNoLength}位");
    }
}